package dao;

import java.sql.SQLException;
import java.util.List;

import om.Bewertung;
import om.Orte;
import om.Route;


import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.criterion.ProjectionList;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class BewertungDao extends HibernateDaoSupport {
	
	/**
	 * Rueckgabewert ist eine Bewertung anhand seiner id aus der Datenbank
	 * @return Ein Objekt vom Typ Bewertung
	 * @see Bewertung
	 */	
	public Bewertung findBewertungById(int bewertungid){
		HibernateTemplate template = getHibernateTemplate();
		return template.load(Bewertung.class, bewertungid);
	}

	
	/**
	 <li> Rueckgabewert ist ein Objekt vom Typ Bewertung 
	 <li>  Speichert ein {@link Bewertung}-s Objekt
	 * @param bewertung Objekt vom Type Bewertung
	 * @param id {@link Route} Dazugeh�rige Route zur Bewertung
	 * @return Ein Objekt vom Typ Bewertung
	 */
	public Bewertung save(Bewertung bewertung, Integer id)
	{
		HibernateTemplate template = getHibernateTemplate();
		Route route = template.get(Route.class, id);
		bewertung.setFs_routenid(route);
		template.saveOrUpdate(bewertung);
		return bewertung;
	}

	 /**
		 * @param routenid Es wird eine id uebergeben und die Datensaetze der Tabelle Bewertung bestimmt
		 * @return Liefert eine Liste von BewertungsObjekten der uebergebenen Route
		 */
	@SuppressWarnings("unchecked")
	public List<Bewertung> getBewertungByRoute(final int routenid){
		HibernateTemplate template = getHibernateTemplate();
		return (List<Bewertung>) template.execute(new HibernateCallback<Object>() {
			
			@Override  
			 public Object doInHibernate(final org.hibernate.Session session)
			   throws HibernateException, SQLException {
				
				final Route route = (Route) session.load(Route.class,routenid);
				final List<Bewertung> bewertung = (List<Bewertung>) session.createCriteria(Bewertung.class)
			    .add(Restrictions.eq("fs_routenid", route))
			    .list();
				return bewertung;
			 }

		});
	 }
	
	 /**
		 * @param routenid Es wird eine id uebergeben und die Datens�tze der Tabelle Bewertung bestimmt
		 * @return Bildet den Durchschnittswert einer Route aus allen Bewertungen im Bereich "Landschaft"
		 */
	 public Double getLandschaftByRoute(final int routenid){
		 HibernateTemplate template = getHibernateTemplate();
		 return (double) template.execute(new HibernateCallback<Double>() {
			 
			 @Override  
			 public Double doInHibernate(final org.hibernate.Session session)
			  throws HibernateException, SQLException {
				 
				 final Route route = (Route) session.load(Route.class,routenid);
				 Criteria crit = session.createCriteria(Bewertung.class)
				  .add(Restrictions.eq("fs_routenid", route));
				  
				 ProjectionList prolist= Projections.projectionList();
				 prolist.add(Projections.avg("landschaft"));
			   	 crit.setProjection(prolist);
			   	
				 return (Double) crit.uniqueResult();
				 }
		 });
	 }
	 
	 /**
		 * @param routenid Es wird eine id �bergeben und die Datens�tze der Tabelle Bewertung bestimmt
		 * @return Bildet den Durchschnittswert einer Route aus allen Bewertungen im Bereich "Physis"
		 */
	 public Double getPhysisByRoute(final int routenid){
		 HibernateTemplate template = getHibernateTemplate();
		 return (double) template.execute(new HibernateCallback<Double>() {
			 
			 @Override  
			 public Double doInHibernate(final org.hibernate.Session session)
			   throws HibernateException, SQLException {
			 
			  final Route route = (Route) session.load(Route.class,routenid);
			  Criteria crit = session.createCriteria(Bewertung.class)
			    .add(Restrictions.eq("fs_routenid", route));
			  
			  	ProjectionList prolist= Projections.projectionList();
				prolist.add(Projections.avg("physis"));
		   		crit.setProjection(prolist);
		   	
			  	return (Double) crit.uniqueResult();
			 }
		 });
	 }
	 
	 
	 
	 /**
	 * @param routenid Es wird eine id uebergeben und der gewuenschte Datensatz aus der Tabelle Route entnommen
	 * @return Bildet den Durchschnittswert einer Route aus allen Bewertungen im Bereich "Technik"
	 */
	public Double getTechnikByRoute(final int routenid){
		 
		 HibernateTemplate template = getHibernateTemplate();
		 return (double) template.execute(new HibernateCallback<Double>() {
			 
			 @Override  
			 public Double doInHibernate(final org.hibernate.Session session)
			   throws HibernateException, SQLException {
				 
				 final Route route = (Route) session.load(Route.class,routenid);
				 Criteria crit = session.createCriteria(Bewertung.class)
				    .add(Restrictions.eq("fs_routenid", route));
				  
				 ProjectionList prolist= Projections.projectionList();
				 prolist.add(Projections.avg("technik"));
			   	 crit.setProjection(prolist);
				 return (Double) crit.uniqueResult();
			 }
		 });
	 }

	 /**
		 * Loescht ein bestimmtes {@link Bewertung}-s Objekt aus der Datenbank
		 * @param route Die {@link Route} deren Bewertungen geloescht werden sollen
		 */
	 public void delete(Route route) {
		 
		   HibernateTemplate template = getHibernateTemplate();
		   List<Bewertung> bewertungen= this.getBewertungByRoute(route.getRouteid());
		   
		   for (Bewertung bewertung : bewertungen) {
		       template.delete(bewertung);
		    }
	 }
}
